home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / System / Idle DA's / Moire.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-05  |  4.7 KB  |  258 lines  |  [TEXT/MACA]

  1. /*
  2.  * moire idle desk accessory
  3.  *
  4.  * bounce points with random speeds
  5.  * generate queue of rectangles
  6.  * inscribe shapes within rectangles
  7.  * draw in XOR mode so stuff at end of queue can be erased 
  8.  *
  9.  * keyboard commands:
  10.  *
  11.  *    [    shorten queue
  12.  *    ]    lengthen queue
  13.  *    q    quantize point speed
  14.  *    0-9    set limit for point speed (0 means none)
  15.  *
  16.  * other keys select shapes (default is rectangle)
  17.  *    o    oval
  18.  *    t    tri-angle
  19.  *    p    penta-gram
  20.  *    ...
  21.  */
  22. #include <hd20:lightspeed:mac:quickdraw.h>
  23.  
  24. #define    nQueue        100    /* max size of queue */
  25. #define    qInit        30    /* initial size of queue */
  26. #define    qIncr        10    /* size increment */
  27.  
  28. int    shape;        /* current shape */
  29. int    quantize;    /* quantize delta's */
  30. long    limit;        /* limit for delta's */
  31. /*
  32.  * bouncing points - 1st is value, 2nd is delta, each w/16 bit fraction
  33.  */
  34. long    x1[2], y1[2],
  35.     x2[2], y2[2];
  36. /*
  37.  * rectangle queue
  38.  */
  39. int    qHead, qTail, qSize, nRinQ;
  40. Rect    rQueue[nQueue];
  41. /*
  42.  * compute new delta
  43.  */
  44. long
  45. newDelta(range)
  46. {
  47.     register int r;
  48.     register long d;
  49.  
  50.     if ((r = Random()) < 0)
  51.         r = -r;
  52.     d = ((long)range << 16) / (r % range + 1);
  53.     if (quantize && (d = (d + 0x7FFFL) & ~0xFFFFL) == 0)
  54.         d = 0x10000L;
  55.     if (limit && d > limit)
  56.         d = limit;
  57.     return d;
  58. }
  59. /*
  60.  * compute new point value - change delta at rails
  61.  */
  62. newPoint(p, lo, hi)
  63. long *p;
  64. int lo, hi;
  65. {
  66.     register int v;
  67.  
  68.     v = p[0] >> 16;
  69.     if (v < lo) {
  70.         v = lo;
  71.         p[1] = newDelta(hi - lo);
  72.     }
  73.     else if (v > hi) {
  74.         v = hi;
  75.         p[1] = -newDelta(hi - lo);
  76.     }
  77.     p[0] += p[1];
  78.     return v;
  79. }
  80. /*
  81.  * draw the current shape
  82.  */
  83. frameShape(s, rp)
  84. int s;
  85. Rect *rp;
  86. {
  87.     register int m, n;
  88.  
  89.     m = rp->left + (rp->right - rp->left) / 2;
  90.     n = rp->top + (rp->bottom - rp->top) / 2;
  91.     switch (s) {
  92.     default:
  93.         FrameRect(rp);
  94.         break;
  95.     case 'o':
  96.         FrameOval(rp);
  97.         break;
  98.     case 't': /* tri-angle */
  99.         MoveTo(m, rp->top);
  100.         LineTo(rp->left, rp->bottom);
  101.         LineTo(rp->right, rp->bottom);
  102.         LineTo(m, rp->top);
  103.         break;
  104.     case 'p': /* pentagram */
  105.         MoveTo(m, rp->top);
  106.         LineTo(rp->right, rp->bottom);
  107.         LineTo(rp->left, n);
  108.         LineTo(rp->right, n);
  109.         LineTo(rp->left, rp->bottom);
  110.         LineTo(m, rp->top);
  111.         break;
  112.     case 'd': /* diamond */
  113.         MoveTo(m, rp->top);
  114.         LineTo(rp->right, n);
  115.         LineTo(m, rp->bottom);
  116.         LineTo(rp->left, n);
  117.         LineTo(m, rp->top);
  118.         break;
  119.     case 'h': /* hour glass */
  120.         MoveTo(rp->left, rp->top);
  121.         LineTo(rp->right, rp->top);
  122.         LineTo(rp->left, rp->bottom);
  123.         LineTo(rp->right, rp->bottom);
  124.         LineTo(rp->left, rp->top);
  125.         break;
  126.     case 'x':
  127.         MoveTo(rp->left, rp->top);
  128.         LineTo(rp->right, rp->bottom);
  129.         MoveTo(rp->right, rp->top);
  130.         LineTo(rp->left, rp->bottom);
  131.         break;
  132.     case 'v':
  133.         MoveTo(rp->left, rp->top);
  134.         LineTo(m, rp->bottom);
  135.         LineTo(rp->right, rp->top);
  136.         break;
  137.     case '\\':
  138.         MoveTo(rp->left, rp->top);
  139.         LineTo(rp->right, rp->bottom);
  140.         break;
  141.     case '/':
  142.         MoveTo(rp->right, rp->top);
  143.         LineTo(rp->left, rp->bottom);
  144.         break;
  145.     case '+':
  146.         MoveTo(m, rp->top);
  147.         LineTo(m, rp->bottom);
  148.         MoveTo(rp->right, n);
  149.         LineTo(rp->left, n);
  150.         break;
  151.     }
  152. }
  153. /*
  154.  * change shape - redraw stuff in queue
  155.  */
  156. newShape(s)
  157. {
  158.     register int x, n;
  159.  
  160.     if (s == shape)
  161.         return;
  162.     ObscureCursor();
  163.     x = qHead;
  164.     n = nRinQ;
  165.     while (n-- > 0) {
  166.         frameShape(shape, &rQueue[x]);
  167.         frameShape(s, &rQueue[x]);
  168.         if (++x >= nQueue)
  169.             x = 0;
  170.     }
  171.     shape = s;
  172. }
  173. /*
  174.  * initialize stuff
  175.  */
  176. initIdle(rp)
  177. Rect *rp;
  178. {
  179.     shape = 'o';
  180.     limit = 0;
  181.     quantize = 0;
  182.     nRinQ = 0;
  183.     qHead = 0;
  184.     qTail = 0;
  185.     qSize = qInit;
  186.  
  187.     x1[1] = newDelta(rp->right - rp->left);
  188.     x1[0] = ((long)rp->right << 16) + x1[1];
  189.     y1[1] = newDelta(rp->bottom - rp->top);
  190.     y1[0] = ((long)rp->top << 16) + y1[1];
  191.     
  192.     x2[1] = -newDelta(rp->right - rp->left);
  193.     x2[0] = ((long)rp->left << 16) + x2[1];
  194.     y2[1] = -newDelta(rp->bottom - rp->top);
  195.     y2[0] = ((long)rp->bottom << 16) + y2[1];
  196. }
  197. /*
  198.  * one step of the way...
  199.  */
  200. runIdle(rp)
  201. Rect *rp;
  202. {
  203.     Point p1, p2;
  204.  
  205.     ObscureCursor();
  206.     /*
  207.      * undraw stuff at the head - shorten if necessary
  208.      */
  209.     while (nRinQ >= qSize) {
  210.         frameShape(shape, &rQueue[qHead]);
  211.         if (++qHead >= nQueue)
  212.             qHead = 0;
  213.         --nRinQ;
  214.     }
  215.     /*
  216.      * compute new rectangle
  217.      */
  218.     p1.h = newPoint(x1, rp->left, rp->right);
  219.     p1.v = newPoint(y1, rp->top, rp->bottom);
  220.     p2.h = newPoint(x2, rp->left, rp->right);
  221.     p2.v = newPoint(y2, rp->top, rp->bottom);
  222.     /*
  223.      * add rectangle to queue
  224.      */
  225.     Pt2Rect(p1, p2, &rQueue[qTail]);
  226.     frameShape(shape, &rQueue[qTail]);
  227.     if (++qTail >= nQueue)
  228.         qTail = 0;
  229.     ++nRinQ;
  230. }
  231. /*
  232.  * key events come here
  233.  */
  234. keyIdle(c)
  235. {
  236.     switch (c) {
  237.     case '[':    /* shorten */
  238.         if ((qSize -= qIncr) < qIncr)
  239.             qSize = qIncr;
  240.         break;
  241.     case ']':    /* lengthen */
  242.         if ((qSize += qIncr) > nQueue)
  243.             qSize = nQueue;
  244.         break;
  245.     default:
  246.         newShape(c);
  247.         break;
  248.     case 'q':
  249.         quantize = !quantize;
  250.         break;
  251.     case '0': case '1': case '2': case '3': case '4':
  252.     case '5': case '6': case '7': case '8': case '9':
  253.         limit = (long)(c - '0') << 17;
  254.         break;
  255.     }
  256.     return 0;
  257. }
  258.